﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OOAD_Project_Engine.Domain.Entities;
using OOAD_Project_Engine.Domain.Components;
using OOAD_Project_Engine.Domain.Factories;
using Microsoft.Xna.Framework;
using OOAD_Project_Engine.Foundation.Interfaces;
using Microsoft.Xna.Framework.Graphics;
using OOAD_Project_Editor.Foundation;
using ThirdPartyNinjas.XnaUtility;
using OOAD_Project_Engine.Foundation;
using OOAD_Project_Engine.Application.Services;
using Microsoft.Xna.Framework.Input;

namespace OOAD_Project_Editor.Foundation
{
    public class SelectionBound : DrawableGameComponent, ISelection
    {
        public IEntity Target { get; set; }
        Vector2 size;
        Vector2 scale;
        Vector2 origin;
        Vector2 topLeft, topRight, downLeft, downRight, originP;
        XmlTexture xmlTexture;
        string vertexId = "selectVertex";
        string centerId = "selectCenter";
        Matrix m = Matrix.Identity;

        public SelectionBound(Game game)
            : base(game)
        {
            size = Vector2.Zero;
            scale = Vector2.One;
            origin = Vector2.Zero;

            xmlTexture = new XmlTexture("image/editerImages");

            Visible = false;
            IsDraging = false;
            DrawOrder = 100;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            updateBound();

        }

        private void updateBound()
        {
            if (Target != null)
            {
                Transform t = Target.Find<Transform>();
                Sprite s = Target.Find<Sprite>();
                if (t != null && s != null)
                {
                    size = s.Size;
                    scale = t.Scale;
                    origin = s.Origin;
                    m = t.World;
                    Visible = true;
                }

                Vector2 _base = Vector2.Zero;
                topLeft = _base - origin * size;
                topRight = topLeft + new Vector2(size.X, 0);
                downLeft = topLeft + new Vector2(0, size.Y);
                downRight = topLeft + size;
                originP = _base;
            }
            else
                Visible = false;
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            SpriteBatch spriteBatch = GameHelper.GetService<IGraphicService>().SpriteBatch;
            DrawSelectedComponent(spriteBatch);
        }

        protected void DrawSelectedComponent(SpriteBatch spriteBatch)
        {
            DrawXmlTexture(xmlTexture, vertexId, topLeft, 0, spriteBatch);
            DrawXmlTexture(xmlTexture, vertexId, downLeft, 0, spriteBatch);
            DrawXmlTexture(xmlTexture, vertexId, downRight, 0, spriteBatch);
            DrawXmlTexture(xmlTexture, vertexId, topRight, 0, spriteBatch);
            DrawXmlTexture(xmlTexture, centerId, originP, 0, spriteBatch);
        }

        protected void DrawXmlTexture(XmlTexture xmlTexture, string id, Vector2 pos, float rotation, SpriteBatch spriteBatch)
        {
            TextureRegion region = xmlTexture.GetRegion(id);
            Rectangle bound = region.Bounds;
            Vector2 _scale = new Vector2(1f / scale.X, 1f / scale.Y);
            Graphic.DrawTexture(spriteBatch, xmlTexture.Texture2D, bound, pos, Color.White, 1, 0, region.OriginCenter, _scale, SpriteEffects.None, m);
        }

        public bool IsDraging { get; private set; }

        Vector2 firstMP = Vector2.Zero;
        Vector2 firstTP = Vector2.Zero;
        public void DragStarted()
        {
            IsDraging = true;
            MouseState ms = Mouse.GetState();
            firstMP = new Vector2(ms.X, ms.Y);
            if (Target.Contains<Transform>())
            {
                Transform t = Target.Find<Transform>();
                firstTP = t.Position;
            }
        }

        public void Draging()
        {
            if (IsDraging)
            {
                MouseState ms = Mouse.GetState();
                Vector2 p = new Vector2(ms.X, ms.Y);
                if (Target.Contains<Transform>())
                {
                    Vector2 dp = p - firstMP;
                    Transform t = Target.Find<Transform>();
                    t.Position = firstTP+dp;
                }
            }
        }

        public void DragEnded()
        {
            IsDraging = false;
            firstMP = Vector2.Zero;
            firstTP = Vector2.Zero;
        }


    }
}
